let rule = {}
// import { compile } from 'vue-template-compiler';
export const getTemplateByJson = (para = {}) => {
    let { json, str, conf, replaceMap = {} } = para;
    rule = {};
    // json = testJson
    itemMap = Object.assign(replaceMap, {
        "this.": "",
        "varys.": "",
    });

    if (json.selfIndex == "form" && !json.comName) {
        //表单
        json.comName = "el-form";
        delete json.props;
    }
    let res = getCom(json);
    Object.keys(itemMap).forEach((k) => {
        res = res.replaceAll(k, itemMap[k]);
    });
    return res;
    // let tree = compile(res)
};

let itemMap;
const getCom = (json) => {
    if (json.formItemProps?.label || json.formItemProps?.prop) {
        //表单元素
        let prop = deepClone(json.formItemProps);
        delete json["formItemProps"];
        let njson = {
            comName: "el-form-item",
            ...prop,
            childNode: [deepClone(json)],
        };
        if ("label" in json) {
            njson["label"] = json.label;
            delete json["label"];
        }
        if ("_v_if" in json) {
            njson["_v_if"] = json._v_if;
            delete json["_v_if"];
        }
        if ("rulelabel" in njson) {
            njson["label"] = njson.rulelabel;
            delete njson["rulelabel"];
        }
        if ("_rulelabel" in njson) {
            njson["_label"] = njson._rulelabel;
            delete njson["_rulelabel"];
        }
        if ("_label" in json) {
            njson["_label"] = json._label;
            delete json["_label"];
        }
        json = njson;
    }
    let comName = toCamelCase1(json.comName.trim());
    let extStrArr = getTemplate(json);
    let propStr = getProp(json);
    let childStr = "";

    if (json.childNode?.length) {
        //子组件
        childStr += getChild(json.childNode);
    } else if (json.template?.length) {
        //row
        let rowArr = json.template.map((e) => {
            e.comName = "el-row";
            return e;
        });
        childStr += getChild(rowArr);
    } else if (
        typeof json.template === "object" &&
        !Array.isArray(json.template) &&
        json.template !== null
    ) {
        //单渲染组件？
        childStr += getChild([json.template]);
    } else if (json.components) {
        //渲染col 后渲染com
        let allowKeys = [
            "offset",
            "push",
            "v_if",
            "span",
            "pull",
            "xs",
            "sm",
            "md",
            "lg",
            "xl",
            "tag",
        ];
        let colArr = json.components.map((e) => {
            let item = {
                comName: "el-col",
                childNode: [e],
            };
            Object.keys(e).forEach((k) => {
                let val = e[k];
                if (val === "") return;

                if (allowKeys.includes(k.slice(1)) || allowKeys.includes(k)) {
                    item[k] = val;
                    delete e[k];
                }
            });
            return item;
        });
        childStr += getChild(colArr);
    } else if (json["contentText"]) {
        childStr += json["contentText"];
        delete json["contentText"];
    } else if (json["_contentText"]) {
        let item = json["_contentText"];
        Object.keys(itemMap).forEach((k) => {
            item = item.replaceAll(k, itemMap[k]);
        });
        childStr = `{{${item}}}`;
        delete json["_contentText"];
    }
    let comStr = `  <${comName}   ${propStr} \n>${childStr}\n</${comName}> \n `;
    if (comName === "img") return `  <${comName}   ${propStr} \n/>`;
    return extStrArr[0] + comStr + extStrArr[1];
};
const getChild = (para = []) => {
    let str = "";
    let slotMap = {};
    para.forEach((e) => {
        try {
            if (e.slotName) {
                if (!slotMap[e.slotName]) slotMap[e.slotName] = [];
                slotMap[e.slotName].push(e);
            } else str += getCom(e);
        } catch (error) { }
    });
    Object.keys(slotMap).forEach((slotName) => {
        let comList = slotMap[slotName];
        let comStr = "";
        comList.forEach((com) => {
            comStr += getCom(com);
        });
        let extStrArr = getTemplate(comList[0], "slotName");
        str += extStrArr[0] + comStr + extStrArr[1];
    });
    return str;
};
const getTemplate = (json, prop = "_v_for") => {
    let strArr = ["", ""];
    if (json["slotName"] && prop == "slotName") {
        strArr[0] = `<template #${json["slotName"]}>`;
        strArr[1] = `</template>`;
    }
    if (Array.isArray(json["v_for"]) && prop == "_v_for") {
        let narr = json["v_for"].map((e, i) => {
            let item = e;
            if (i == 0 && Array.isArray(item)) {
                item = JSON.stringify(item).replaceAll('"', "'");
            }
            return item;
        });
        let key = json["_key"] ?? "i";
        // Object.keys(itemMap).forEach((k) => {
        //   key = key.replaceAll(k, itemMap[k]);
        // });
        strArr[0] += `<template v-for="(${narr[1]},${narr[2] ?? "ii"}) in ${narr[0]
            }"  :key="${key}"  >`;
        strArr[1] += `</template>`;
    }
    if (json["_v_for"] && prop == "_v_for") {
        let arr = json["_v_for"].slice(1).slice(0, -1).split(",");
        let narr = arr.map((e, i) => {
            let item = e;
            if (i == 0) {
                Object.keys(itemMap).forEach((k) => {
                    item = item.replaceAll(k, itemMap[k]);
                });
            } else {
                item = item.replaceAll("'", "").replaceAll('"', "");
            }
            return item;
        });
        let key = json["_key"] ?? "i";
        Object.keys(itemMap).forEach((k) => {
            key = key.replaceAll(k, itemMap[k]);
        });
        strArr[0] += `<template v-for="(${narr[1]},${narr[2] ?? "ii"}) in ${narr[0]
            }"  :key="${key}"  >`;
        strArr[1] += `</template>`;
    }
    return strArr;
};
const getProp = (json) => {
    let str = "";
    let propMap = {
        childNode: null,
        v_if: "v-if",
        v_show: "v-show",
        v_for: null,
        slotName: null,
        selfIndex: null,
        // key: null,
        contentText: null,
        belongParent: null,
        comName: null,
        rulelabel: "label",
    };
    Object.keys(json).forEach((k) => {
        let nk = k;
        let item = json[k];
        if (typeof json[k] == "object" && !Array.isArray(item)) return; //?
        if (typeof item == "string") {
            Object.keys(itemMap).forEach((k) => {
                item = item.replaceAll(k, itemMap[k]);
            });
        }
        let isSaveProp = true;
        if (k.startsWith("_")) {
            if (!k.startsWith("_v_")) {
                nk = ":" + k.slice(1);
            } else nk = k.slice(1);
            if (k.startsWith("_on") || k.startsWith("on")) {
                let str = k.replace("_on", "");
                str = str.charAt(0).toLowerCase() + str.slice(1);
                nk = "@" + str;
            }
        }

        Object.keys(propMap).forEach((ii) => {
            if (nk.includes(ii)) {
                if (propMap[ii]) {
                    nk = nk.replace(ii, propMap[ii]);
                } else {
                    isSaveProp = false;
                }
            }
        });
        if (k == "v_model") {
            let nstr = item;

            nk = "v-model";
            if (Array.isArray(item)) {
                item.forEach((e, i) => {
                    if (i == 0) nstr = e;
                    else {
                        nstr += "['" + e + "']";
                    }
                });
                item = nstr;
            }
        }
        if (!Number.isNaN(parseFloat(item)) && Number.isFinite(item)) {
            if (nk.startsWith(":")) {
            } else {
                nk = ":" + nk;
            }
        }
        if (
            item === "true" ||
            item === "false" ||
            item === true ||
            item === false
        ) {
            nk = ":" + nk;
        }
        isSaveProp && (str += ` ${nk} = "${item}" \n`);
    });
    let prop = json.prop ?? json._prop;
    if (json.comName == "el-form-item" && prop) {
        ////?如何根据配置生成validate？
        rule[prop] = { ...json, childNode: undefined };
    }
    return str;
};
function strToLower(str) {
    try {
        return str
            .replace(/([A-Z])/g, "-$1")
            .toLowerCase()
            .substring(1);
    } catch (error) { }
}
function toCamelCase1(str) {
    // 将字符串按照 - 或 _ 进行分割
    const words = str.split(/[-_]/);
    // 将第一个单词保持不变，其余单词首字母大写后拼接
    const result = words.reduce((acc, curr, index) => {
        if (index === 0 && curr !== "el") {
            // 不对第一个单词进行修改
            return curr + acc;
        }
        //return str
        // 将首字母大写后拼接
        return acc + curr.charAt(0).toUpperCase() + curr.slice(1);
    }, "");
    if (result.startsWith("El")) return strToLower(result);
    return result;
}
function toCamelCase(str) {
    // 将字符串按照 - 或 _ 进行分割
    const words = str.split(/[-_]/);
    // 将第一个单词保持不变，其余单词首字母大写后拼接
    const result = words.reduce((acc, curr, index) => {
        if (index === 0 && curr !== "el") {
            // 不对第一个单词进行修改
            return curr + acc;
        }
        //return str
        // 将首字母大写后拼接
        return acc + curr.charAt(0).toUpperCase() + curr.slice(1);
    }, "");
    if (result.startsWith('El')) return strToLower(result)
    return result;
}
const deepClone = (obj) => {
    if (obj === null) return null // 如果是 null 直接返回 null
    if (typeof obj !== "object") return obj // 如果 obj 没有子属性直接返回 obj

    let clone = Array.isArray(obj) ? [] : {}
    for (let key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            clone[key] = deepClone(obj[key]) // 递归调用 deepClone 进行深度拷贝
        }
    }
    return clone
}